package com.jiangjiang.eshop.commodity.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiangjiang.eshop.commodity.convert.CategoryConvert;
import com.jiangjiang.eshop.commodity.dao.CategoryMapper;
import com.jiangjiang.eshop.commodity.domain.CategoryEntity;
import com.jiangjiang.eshop.commodity.dto.CategoryDTO;
import com.jiangjiang.eshop.commodity.dto.CategoryPropertyRelationshipDTO;
import com.jiangjiang.eshop.commodity.dto.PropertyGroupDTO;
import com.jiangjiang.eshop.commodity.operation.Category;
import com.jiangjiang.eshop.commodity.operation.RelatedCheckCategoryOperation;
import com.jiangjiang.eshop.commodity.operation.RemoveCategoryOperation;
import com.jiangjiang.eshop.common.bean.SpringApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName CategoryService
 * @Description
 * @Author jhw
 * @Date 2021/6/20 14:51
 * @Version 1.0
 **/

@Service
public class CategoryService extends ServiceImpl<CategoryMapper, CategoryEntity> {
    @Autowired
    private CategoryConvert categoryConvert;
    @Autowired
    private CategoryPropertyRelationshipService categoryPropertyRelationshipService;
    @Autowired
    private PropertyGroupService propertyGroupService;
    @Autowired
    private SpringApplicationContext context;


    /**
     * 查询所有父级类目
     *
     * @return
     */
    public List<CategoryDTO> listRoot() {
        LambdaQueryWrapper<CategoryEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.isNull(CategoryEntity::getParentId);
        return categoryConvert.convertEntities2DTOList(this.getBaseMapper().selectList(wrapper));
    }

    /**
     * 根据父级类目查询子集类目id
     *
     * @param parentId 父级类目id
     * @return 子类目id
     */
    public List<CategoryDTO> listChildren(Long parentId) {
        LambdaQueryWrapper<CategoryEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CategoryEntity::getParentId, parentId);
        return categoryConvert.convertEntities2DTOList(this.getBaseMapper().selectList(wrapper));
    }

    /**
     * 类目保存
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveCategory(CategoryDTO dto) {
        // 保存类目
        CategoryEntity entity = categoryConvert.convertDTO2Entity(dto);
        this.save(entity);
        dto.setId(entity.getId());

        // 保存类目属性关联关系
        List<CategoryPropertyRelationshipDTO> relationshipDTOList = dto.getPropertyRelations()
                .stream()
                .peek(relation -> relation.setCategoryId(dto.getId()))
                .collect(Collectors.toList());
        categoryPropertyRelationshipService.saveBatch(relationshipDTOList);

        // 保存属性分组
        List<PropertyGroupDTO> groupDTOList = dto.getPropertyGroups()
                .stream()
                .peek(group -> group.setCategoryId(dto.getId()))
                .collect(Collectors.toList());
        propertyGroupService.saveBatch(groupDTOList);

        return  Boolean.TRUE;
    }

    /**
     * 根据id查询类目
     * @param id 类目id
     * @return 查询结果
     */
    public CategoryDTO queryById(Long id) {
        // 略
        return null;
    }

    /**
     * 更新类目
     * @param dto 类目数据
     * @return 处理结果
     */
    public Boolean categoryUpdate(CategoryDTO dto) {
        // 纯义务逻辑处理 暂时不进行编写
        return null;
    }

    /**
     * 类目删除
     * @param id
     * @return
     */
    public Boolean categoryRemove(Long id) throws Exception {
        Category category = new Category(id);
        RelatedCheckCategoryOperation relateOperation = context.getBean(RelatedCheckCategoryOperation.class);
        Boolean result = category.execute(relateOperation);
        if(result){
            return false;
        }
        RemoveCategoryOperation removeOperation = context.getBean(RemoveCategoryOperation.class);
        return category.execute(removeOperation);
    }
}
